<template>
    <div class="run-box">
        <div class="btn-wrap">
            <Button size="large" class="btn" type="primary" @click="handleRun">运行</Button>
            <Button size="large" class="btn" @click="handleResetCode">重置</Button>
        </div>
        <div class="panel">
            <Row>
                <Split v-model="split">
                    <div slot="left" class="split-pane">
                        <textarea
                            ref="cmRef"
                            v-model="cmOptions.value"
                            class="code"
                            :options="cmOptions"
                        ></textarea>
                    </div>
                    <div slot="right" class="split-pane">
                        <div id="renderComponent"></div>
                    </div>
                </Split>
            </Row>
        </div>
        <Modal v-model="modal1" title="重置确认" @on-ok="handleSure">
            <p>确认重置该编译器吗</p>
        </Modal>
    </div>
</template>
<script>
function newGuid() {
    var S4 = function() {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    };
    return S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4();
}
import Vue from "vue";

let CodeMirror = require("codemirror/lib/codemirror");
//括号匹配
require("codemirror/addon/edit/matchbrackets");
//高亮行
require("codemirror/addon/selection/active-line");
// 代码折叠
require("codemirror/addon/fold/foldcode.js");
require("codemirror/addon/fold/foldgutter.js");
require("codemirror/addon/fold/brace-fold.js");
require("codemirror/addon/fold/comment-fold.js");
require("codemirror/addon/edit/closetag.js");
// 自动补全
require("codemirror/addon/hint/show-hint.js");
import "codemirror/mode/vue/vue";

let strVue = `<template>\n\t<div>\n\t\t<Alert show-icon>当前 View UI（iView）版本为 4.1.3</Alert>\n\t<\/div>\n<\/template>\n\n<script>\n\texport default {\n\t\tdata () {\n\t\t\treturn {\n\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\n\t\t},\n\t\tmounted () {\n\n\t\t}\n\n\t}\n<\/script>\n\n<style>\n\n<\/style>`;
// import Preview from '@/utils/preview'
import parser from "./parser";
import compiler from "./compiler";
import "codemirror/lib/codemirror.css";
import "codemirror/theme/monokai.css";
import "codemirror/addon/hint/show-hint.css";

//import 'codemirror/addon/hint/javascript-hint';
import "codemirror/addon/fold/foldgutter.css";

export default {
    name: "CODERUN",
    data() {
        return {
            split: 0.5,
            isShow: false,
            modal1: false,
            styleId: "",
            cmOptions: {
                value: strVue,
                mode: "text/x-vue",
                // mode:"javascript",
                tabSize: 2,
                theme: "monokai",
                indentWithTabs: true,
                smartIndent: true,
                lineNumbers: true,
                lineWrapping: true,
                cursorHeight: 1, // 光标高度
                dragDrop: true,
                autoRefresh: true,
                autoCloseTags: true,
                autofocus: true,
                foldGutter: true, // 启用行槽中的代码折叠
                extraKeys: {
                    "Ctrl-Space": "autocomplete"
                },
                gutters: [
                    "CodeMirror-linenumbers",
                    "CodeMirror-foldgutter",
                    "CodeMirror-lint-markers"
                ],
                hintOptions: {
                    //自定义提示选项
                    tables: {
                        users: ["name", "score", "birthDate"],
                        countries: ["name", "population", "size"]
                    }
                },
                matchBrackets: true, // 匹配结束符号，比如"]、}"
                autoCloseBrackets: true, // 自动闭合符号
                styleActiveLine: true // 显示选中行的样式
            },
            editor: ""
        };
    },

    components: {},
    beforeCreate() {},
    created() {
        this.cmOptions.value = localStorage.getItem("currentCode") || strVue;
        localStorage.removeItem("currentCode");
    },
    mounted() {
        this.$nextTick(() => {
            setTimeout(() => {
                this.initCode();
            }, 0);
        });
    },
    methods: {
        initCode() {
            this.editor = CodeMirror.fromTextArea(
                this.$refs.cmRef,
                this.cmOptions
            );
            //this.editor.setValue(this.cmOptions.value);
            this.handleRun();
        },
        handleSure() {
            this.editor.setValue(strVue);
            this.handleRun();
        },
        handleResetCode() {
            this.modal1 = true;
        },
        handleRun() {
            //let content=this.editor.getValue().replace(/[\r\n]/g, "").trim();
            let codeResult = parser(this.editor.getValue());
            const { result, styles } = compiler(codeResult);

            new Vue({
                render: h => h(result)
            }).$mount("#renderComponent");

            this.insertStyle(styles);

            //const Profile = Vue.extend(result);
            /*
             * 渲染方式1;
             */
            //Vue.component("myVue", Profile);
            /*
             * 渲染方式2;
             */
            //new Profile().$mount("#renderComponent");
        },
        //插入样式
        insertStyle(style, scope = "") {
            const regex = /(^|\})\s*([^{]+)/g;

            const head = document.getElementsByTagName("head")[0];
            let styles = style.trim().replace(regex, (m, g1, g2) => {
                return g1 ? `${g1} ${scope} ${g2}` : `${scope} ${g2}`;
            });
            if (this.styleId) {
                document.getElementById(this.styleId).innerHTML = styles;
            } else {
                this.styleId = newGuid();
                let styleEl = document.createElement("style");
                styleEl.type = "text/css";
                styleEl.id = this.styleId;
                styleEl.appendChild(document.createTextNode(styles));
                head.appendChild(styleEl);
            }
        }
    }
};
</script>
<style lang="less" scoped>
.run-box {
    position: relative;
    height: 100%;
    min-height: 500px;
}
/deep/ .CodeMirror {
    height: 100% !important;
    font-size: 16px;
}

.btn-wrap {
    padding: 12px;

    .btn {
        margin-left: 8px;
    }
}

.split-pane {
    padding: 12px;
    height: 100%;
}
.code {
    height: 100%;
}
.panel {
    position: absolute;
    left: 0;
    right: 0;
    top: 80px;
    bottom: 0;
    width: 100%;
    padding: 0 12px;
    /deep/ .ivu-row {
        height: 100%;
    }

    .slide {
        border-right: 10px solid #f8f8f8;
    }
}
</style>